﻿using AutoMapper;
using DTcms.Core.API.Filters;
using DTcms.Core.Common.Emum;
using DTcms.Core.Common.Extensions;
using DTcms.Core.Common.Helper;
using DTcms.Core.IServices;
using DTcms.Core.Model.Models;
using DTcms.Core.Model.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;

namespace DTcms.Core.API.Controllers
{
    /// <summary>
    /// 会员收货地址
    /// </summary>
    [Area("api")]
    [Route("api/admin/member/address")]
    [ApiController]
    public class MemberAddressController : ControllerBase
    {
        private readonly IMemberAddressService _memberAddressService;
        private readonly IUserService _userService;
        private readonly IMapper _mapper;

        /// <summary>
        /// 依赖注入
        /// </summary>
        public MemberAddressController(IMemberAddressService memberAddressService, IUserService userService, IMapper mapper)
        {
            _memberAddressService = memberAddressService;
            _userService = userService;
            _mapper = mapper;
        }

        #region 管理员调用接口==========================
        /// <summary>
        /// 根据ID获取数据
        /// 示例：/api/admin/member/address/1
        /// </summary>
        [HttpGet("{id}")]
        [Authorize]
        [AuthorizeFilter("MemberAddress", ActionType.View)]
        public async Task<IActionResult> GetById([FromRoute] long id, [FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //查询数据库获取实体
            var resultFrom = await _memberAddressService.QueryAsync(x => x.Id == id, WriteRoRead.Write);
            if (resultFrom == null)
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //根据字段进行塑形
            var result = resultFrom.ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 获取指定数量列表
        /// 示例：/api/admin/member/address/view/0
        /// </summary>
        [HttpGet("view/{top}")]
        [Authorize]
        [AuthorizeFilter("MemberAddress", ActionType.View)]
        public async Task<IActionResult> GetList([FromRoute] int top, [FromQuery] BaseParameter searchParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }

            //获取数据库列表
            var resultFrom = await _memberAddressService.QueryListAsync(top,
                x => !searchParam.Keyword.IsNotNullOrEmpty() || (x.AcceptName != null && x.AcceptName.Contains(searchParam.Keyword)),
                searchParam.OrderBy ?? "AddTime");
            //根据字段进行塑形
            var result = resultFrom.ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(result);
        }

        /// <summary>
        /// 获取分页列表
        /// 示例：/api/admin/member/address?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet]
        [Authorize]
        [AuthorizeFilter("MemberAddress", ActionType.View)]
        public async Task<IActionResult> GetList([FromQuery] BaseParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _memberAddressService.QueryPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => !searchParam.Keyword.IsNotNullOrEmpty() || (x.AcceptName != null && x.AcceptName.Contains(searchParam.Keyword)),
                searchParam.OrderBy ?? "-AddTime,-Id");

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //根据字段进行塑形，注意因为没有使用AotoMapper，所以要转换成Enumerable
            var resultDto = list.AsEnumerable<MemberAddressDto>().ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }


        /// <summary>
        /// 添加一条记录
        /// 示例：/api/admin/member/address
        /// </summary>
        [HttpPost]
        [Authorize]
        [AuthorizeFilter("MemberAddress", ActionType.Add)]
        public async Task<IActionResult> Add([FromBody] MemberAddressEditDto modelDto)
        {
            //检查会员是否存在
            if (!await _memberAddressService.ExistsAsync<Members>(x => x.UserId == modelDto.UserId))
            {
                return BadRequest(ResponseMessage.Error($"会员ID[{modelDto.UserId}]不存在"));
            }
            modelDto.Address = $"{modelDto.Province},{modelDto.City},{modelDto.Area},{modelDto.Address}";
            //映射成实体
            var model = _mapper.Map<MemberAddress>(modelDto);
            //写入数据库
            await _memberAddressService.AddAsync(model);
            //重新联合查询
            var result = await _memberAddressService.QueryAsync(x => x.Id == model.Id, WriteRoRead.Write);
            return Ok(result);
        }

        /// <summary>
        /// 修改一条记录
        /// 示例：/api/admin/member/address/1
        /// </summary>
        [HttpPut("{id}")]
        [Authorize]
        [AuthorizeFilter("MemberAddress", ActionType.Edit)]
        public async Task<IActionResult> Update([FromRoute] long id, [FromBody] MemberAddressEditDto modelDto)
        {
            //查找记录
            var model = await _memberAddressService.QueryAsync<MemberAddress>(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //保存到数据库
            if (modelDto.Address != null)
            {
                var addressArr = modelDto.Address.Split(',');//将详细地址拆分，重新组合
                modelDto.Address = $"{modelDto.Province},{modelDto.City},{modelDto.Area},{addressArr[^1]}";
            }
            _mapper.Map(modelDto, model);
            var result = await _memberAddressService.UpdateAsync(model);
            return NoContent();
        }

        /// <summary>
        /// 局部更新一条记录
        /// 示例：/api/admin/member/address/1
        /// Body：[{"op":"replace","path":"/title","value":"new title"}]
        /// </summary>
        [HttpPatch("{id}")]
        [Authorize]
        [AuthorizeFilter("MemberAddress", ActionType.Edit)]
        public async Task<IActionResult> Update([FromRoute] long id, [FromBody] JsonPatchDocument<MemberAddressEditDto> patchDocument)
        {
            //检查记录是否存在
            var model = await _memberAddressService.QueryAsync<MemberAddress>(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }

            var modelToPatch = _mapper.Map<MemberAddressEditDto>(model);
            patchDocument.ApplyTo(modelToPatch, ModelState);
            //验证数据是否合法
            if (!TryValidateModel(modelToPatch))
            {
                return ValidationProblem(ModelState);
            }
            //更新操作AutoMapper替我们完成，只需要调用保存即可
            _mapper.Map(modelToPatch, model);
            await _memberAddressService.SaveAsync();
            return NoContent();
        }

        /// <summary>
        /// 删除一条记录
        /// 示例：/api/admin/member/address/1
        /// </summary>
        [HttpDelete("{id}")]
        [Authorize]
        [AuthorizeFilter("MemberAddress", ActionType.Delete)]
        public async Task<IActionResult> Delete([FromRoute] long id)
        {
            //检查参数是否正确
            if (!await _memberAddressService.ExistsAsync<MemberAddress>(x => x.Id == id))
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            var result = await _memberAddressService.DeleteAsync<MemberAddress>(x => x.Id == id);
            return NoContent();
        }

        /// <summary>
        /// 批量删除记录
        /// 示例：/api/admin/member/address?ids=1,2,3
        /// </summary>
        [HttpDelete]
        [Authorize]
        [AuthorizeFilter("MemberAddress", ActionType.Delete)]
        public async Task<IActionResult> DeleteByIds([FromQuery] string Ids)
        {
            //检查参数是否为空
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //将ID列表转换成IEnumerable
            var listIds = Ids.ToIEnumerable<long>();
            if (listIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //执行批量删除操作
            await _memberAddressService.DeleteAsync<MemberAddress>(x => listIds.Contains(x.Id));
            return NoContent();
        }
        #endregion

        #region 当前用户调用接口========================
        /// <summary>
        /// 获取用户一条默认数据
        /// 示例：/api/account/member/address
        /// </summary>
        [HttpGet("/api/account/member/address")]
        [Authorize]
        public async Task<IActionResult> AccountGetByUserId([FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //查询数据库获取实体
            var resultFrom = await _memberAddressService.QueryAsync(x => x.UserId == userId && x.IsDefault == 1);
            if (resultFrom == null)
            {
                return BadRequest(ResponseMessage.Error("暂无默认收货地址"));
            }
            //根据字段进行塑形
            var result = resultFrom.ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 根据ID获取用户一条数据
        /// 示例：/api/account/member/address/1
        /// </summary>
        [HttpGet("/api/account/member/address/{id}")]
        [Authorize]
        public async Task<IActionResult> AccountGetById([FromRoute] long id, [FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //查询数据库获取实体
            var resultFrom = await _memberAddressService.QueryAsync(x => x.UserId == userId && x.Id == id);
            if (resultFrom == null)
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //根据字段进行塑形
            var result = resultFrom.ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 获取指定数量列表
        /// 示例：/api/account/member/address/view/0
        /// </summary>
        [HttpGet("/api/account/member/address/view/{top}")]
        [Authorize]
        public async Task<IActionResult> AccountGetList([FromRoute] int top, [FromQuery] BaseParameter searchParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取数据库列表
            var resultFrom = await _memberAddressService.QueryListAsync(top,
                x => x.UserId == userId
                && !searchParam.Keyword.IsNotNullOrEmpty() || (x.AcceptName != null && x.AcceptName.Contains(searchParam.Keyword)),
                searchParam.OrderBy ?? "-IsDefault,-AddTime");
            //根据字段进行塑形
            var result = resultFrom.ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(result);
        }

        /// <summary>
        /// 获取分页列表
        /// 示例：/api/account/member/address/list?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet("/api/account/member/address/list")]
        [Authorize]
        public async Task<IActionResult> AccountGetList([FromQuery] BaseParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<MemberAddressDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _memberAddressService.QueryPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => x.UserId == userId
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.AcceptName != null && x.AcceptName.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "-AddTime,-Id");

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //根据字段进行塑形，注意因为没有使用AotoMapper，所以要转换成Enumerable
            var resultDto = list.AsEnumerable<MemberAddressDto>().ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        /// <summary>
        /// 添加一条记录
        /// 示例：/api/account/member/address
        /// </summary>
        [HttpPost("/api/account/member/address")]
        [Authorize]
        public async Task<IActionResult> AccountAdd([FromBody] MemberAddressEditDto modelDto)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            modelDto.UserId = userId; //赋值当前用户
            modelDto.Address = $"{modelDto.Province},{modelDto.City},{modelDto.Area},{modelDto.Address}";
            //映射成实体
            var model = _mapper.Map<MemberAddress>(modelDto);
            //写入数据库
            await _memberAddressService.AddAsync(model);
            //重新联合查询
            var result = await _memberAddressService.QueryAsync(x => x.Id == model.Id, WriteRoRead.Write);
            return Ok(result);
        }

        /// <summary>
        /// 修改一条记录
        /// 示例：/api/account/member/address/1
        /// </summary>
        [HttpPut("/api/account/member/address/{id}")]
        [Authorize]
        public async Task<IActionResult> AccountUpdate([FromRoute] long id, [FromBody] MemberAddressEditDto modelDto)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                return BadRequest(ResponseMessage.Error("用户尚未登录"));
            }
            //查找记录
            var model = await _memberAddressService.QueryAsync<MemberAddress>(x => x.UserId == userId && x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //赋值保存到数据库
            modelDto.UserId = userId;
            if (modelDto.Address != null)
            {
                var addressArr = modelDto.Address.Split(',');//将详细地址拆分，重新组合
                modelDto.Address = $"{modelDto.Province},{modelDto.City},{modelDto.Area},{addressArr[^1]}";
            }
            _mapper.Map(modelDto, model);
            var result = await _memberAddressService.UpdateAsync(model);
            return NoContent();
        }

        /// <summary>
        /// 删除一条记录
        /// 示例：/api/account/member/address/1
        /// </summary>
        [HttpDelete("/api/account/member/address/{id}")]
        [Authorize]
        public async Task<IActionResult> AccountDelete([FromRoute] long id)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                return BadRequest(ResponseMessage.Error("用户尚未登录"));
            }
            //检查参数是否正确
            if (!await _memberAddressService.ExistsAsync<MemberAddress>(x => x.UserId == userId && x.Id == id))
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            var result = await _memberAddressService.DeleteAsync<MemberAddress>(x => x.UserId == userId && x.Id == id);
            return NoContent();
        }
        #endregion
    }
}